package com.ruoyi.web.server.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.biz.CommonUtil;
import com.ruoyi.common.utils.biz.ResultSaveModule;
import com.ruoyi.utils.DbServiceUtil;
import com.ruoyi.web.server.entity.ResultSave;
import com.ruoyi.web.server.mapper.ResultSaveMapper;
import com.ruoyi.web.server.service.ResultSaveService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

import java.io.File;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 参数和文件保存表 服务实现类
 * </p>
 *
 * @author liuhl
 * @since 2024-06-25
 */
@Service
public class ResultSaveServiceImpl extends ServiceImpl<ResultSaveMapper, ResultSave> implements ResultSaveService {

    @Override
    public AjaxResult resultSave(Map<String,Object> paramMap) {
        //1.过滤参数中的value空值
        Iterator<Map.Entry<String, Object>> iterator = paramMap.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry<String, Object> entry = iterator.next();
            Object value = entry.getValue();
            if (value == null || StrUtil.isBlank(value.toString())) {
                iterator.remove();
            }
        }
        String resultData = paramMap.get("resultData").toString();
        paramMap.remove("resultData");
        String module = paramMap.get("module").toString();
        paramMap.remove("module");
        String submodule = paramMap.get("submodule").toString();
        paramMap.remove("submodule");

        String startTime = paramMap.get("startTime") == null ? null : paramMap.get("startTime").toString();
        paramMap.remove("startTime");
        String endTime = paramMap.get("endTime") == null ? null : paramMap.get("endTime").toString();
        paramMap.remove("endTime");

        if (ResultSaveModule.MODEL_CORRECT_PREDICT.equals(submodule)) {
            //大气模型动态修正-动态修正系数建模预报  时间 调整
            //要求 starttime 写入到 param里
            paramMap.put("z_Time", ListUtil.of(startTime, endTime));
        }

        /**开始：经纬度格网化特殊处理 */
        if (ResultSaveModule.DATA_FUSION_GRID.equals(submodule)) {

            List<Map<String, Object>> paramList = (List<Map<String, Object>>) paramMap.get("param");
            List<ResultSave> batchList = new ArrayList<>();
            for (int i = 0; i < paramList.size(); i++) {
                Map<String, Object> params = paramList.get(i);
                String paramStr = params.entrySet().stream()
                        .filter(o -> o.getValue() != null)
                        .map(o -> o.getKey() + Constants.ENTRY_D + o.getValue())
                        .sorted()
                        .collect(Collectors.joining(Constants.FIELD_D));

                startTime = params.get("startTime") == null ? null : params.get("startTime").toString();
                endTime = params.get("endTime") == null ? null : params.get("endTime").toString();

                List<ResultSave> list = list(new LambdaQueryWrapper<ResultSave>()
                                .eq(ResultSave::getModule, module)
                                .eq(ResultSave::getSubmodule, submodule)
                                .eq(ResultSave::getParams, paramStr)
                                .eq(StrUtil.isNotBlank(startTime), ResultSave::getStartTime, startTime)
                                .eq(StrUtil.isNotBlank(endTime), ResultSave::getEndTime, endTime)
                );

                if (CollUtil.isNotEmpty(list)) {
                    removeBatchByIds(list);
                }

                List<String> fileNameList = JSONUtil.parseArray(resultData).toList(String.class)
                        .stream()
                        .map(filePath -> filePath.substring(filePath.lastIndexOf("/") + 1))
                        .collect(Collectors.toList());
                String fileNames = JSONUtil.toJsonStr(fileNameList);

                ResultSave entity = ResultSave.builder()
                        .params(paramStr)
                        .module(module)
                        .submodule(submodule)
                        .resultData(resultData)
                        .fileNames(fileNames)
                        .startTime(startTime)
                        .endTime(endTime)
                        .createTime(new Date())
                        .build();
                batchList.add(entity);
            }
            saveBatch(batchList);
            return AjaxResult.success();
        }

        /**结束：经纬度格网化特殊处理 */

        /**开始：太阳辐射指数预报和地磁指数预报 要额外保存数据 */
        if (ResultSaveModule.MODEL_CAL_SOLAR.equals(submodule) || ResultSaveModule.MODEL_CAL_MAG.equals(submodule)) {

            String index = paramMap.get("index").toString();
            String method = paramMap.get("method").toString();
            String time = paramMap.get("time").toString();
            String filePath = JSONUtil.parseArray(resultData).toList(String.class).get(0).trim();
            String content = CommonUtil.readStrData(new File(filePath), null);
            Map<String, Object> map = JSON.parseObject(content, Map.class);
            List<String> timeList = (List<String>) map.get("DATETIME");
            //获取预报值列表
            List<Object> preds = (List<Object>) map.get("pred");
            if (preds == null) {
                preds = ((List<Object>) map.get("Kp_pred"));
                map.put("pred", preds);
            }
            List<Object> predList = ((List<Object>) map.get("pred")).stream()
                    .map(obj -> {
                        if (obj instanceof Number) {
                            BigDecimal bd = new BigDecimal(obj.toString());
                            bd = bd.setScale(1, RoundingMode.HALF_UP);
                            return bd.doubleValue();
                        }
                        return obj;
                    })
                    .collect(Collectors.toList());

            //保存数据至数据库
            DbServiceUtil.savePreData(index, time, method, timeList, predList);

        }
        /**结束：太阳辐射指数预报和地磁指数预报 要额外保存数据 */

        String params = paramMap.entrySet().stream()
                .filter(o -> o.getValue() != null)
                .map(o -> o.getKey() + Constants.ENTRY_D + o.getValue())
                .sorted()
                .collect(Collectors.joining(Constants.FIELD_D));

        List<String> fileNameList = JSONUtil.parseArray(resultData)
                .toList(String.class)
                .stream()
                .map(filePath -> filePath.substring(filePath.lastIndexOf("/") + 1))
                .collect(Collectors.toList());
        String fileNames = JSONUtil.toJsonStr(fileNameList);

        ResultSave resultSave = ResultSave.builder()
                .params(params)
                .module(module)
                .submodule(submodule)
                .resultData(resultData)
                .fileNames(fileNames)
                .startTime(startTime)
                .endTime(endTime)
                .createTime(new Date())
                .build();

        List<ResultSave> list = list(new LambdaQueryWrapper<ResultSave>()
                        .eq(ResultSave::getModule, module)
                        .eq(ResultSave::getSubmodule, submodule)
                        .eq(ResultSave::getParams, params)
                        .eq(StrUtil.isNotBlank(startTime), ResultSave::getStartTime, startTime)
                        .eq(StrUtil.isNotBlank(endTime), ResultSave::getEndTime, endTime)
        );

        if (CollUtil.isNotEmpty(list)) {
            removeBatchByIds(list);
        }
        save(resultSave);
        return AjaxResult.success("新增成功", "");
    }

}
